package com.edou.auth.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.edou.auth.dao.IDepartDao;
import com.edou.auth.dao.IRoleDao;
import com.edou.auth.dao.IUserDao;
import com.edou.auth.dao.IUserDepartDao;
import com.edou.auth.dao.IUserRoleDao;
import com.edou.auth.dto.UserCondition;
import com.edou.auth.entity.Depart;
import com.edou.auth.entity.Role;
import com.edou.auth.entity.User;
import com.edou.auth.entity.UserDepart;
import com.edou.auth.entity.UserRole;
import com.edou.auth.service.IUserService;
import com.edou.base.constant.SessionConstant;
import com.edou.base.constant.SystemConstant;
import com.edou.base.page.PageResult;
import com.edou.base.service.BaseServiceImpl;
import com.edou.base.util.CommonUtil;
import com.edou.base.util.EncryptUtil;

@Service("userServiceImpl")
@Transactional(value = "transactionManager")
public class UserServiceImpl extends BaseServiceImpl implements IUserService{
	
	@Resource(name = "userDaoImpl")
	private IUserDao userDao;
	@Resource(name = "roleDaoImpl")
	private IRoleDao roleDao;
	@Resource(name = "userRoleDaoImpl")
	private IUserRoleDao userRoleDao;
	@Resource(name = "userDepartDaoImpl")
	private IUserDepartDao userDepartDao;
	@Resource(name = "departDaoImpl")
	private IDepartDao departDao;
	
	
	/**
	 * 查询所有用户
	 */
	public List<User> listUserAll(){
		return userDao.listUserAll();
	}
	
	@Override
	public void listUserByPage(PageResult<User> pageResult,UserCondition condition) {
		//获取总行数
		int count  = userDao.listUserByPageCount(condition);
		pageResult.setRows(count);
		
		//获取结果集
		RowBounds bounds = new RowBounds(pageResult.getCurrentPageIndex(), pageResult.getPageSize());
		List<User> list = userDao.listUserByPage(bounds,condition);
		
		//封装
		pageResult.setResult(list);
		
		for(int i=0;i<list.size();i++){
			User user = list.get(i);
			
			//查询用户角色
			List<Role> roleList = userRoleDao.listRoleByUserId(user.getId());
			if(!CollectionUtils.isEmpty(roleList)){
				List<String> roleNameList = new ArrayList<String>(roleList.size());
				for(Role curRole : roleList){
					roleNameList.add(curRole.getName());
				}
				user.setRoleNames(StringUtils.join(roleNameList,SystemConstant.COMMA));
			}
			
			
			//查询用户部门
			List<Depart> departList = userDepartDao.listDepartByUserId(user.getId());
			if(!CollectionUtils.isEmpty(departList)){
				List<String> departNameList = new ArrayList<String>(departList.size());
				for(Depart curDepart : departList){
					departNameList.add(curDepart.getName());
				}
				user.setDepartNames(StringUtils.join(departNameList,SystemConstant.COMMA));
			}
			
		}
	}
	
	
	@Override
	public User getUserDetailById(String id) {
		User user = userDao.getUserById(id);
		if(null != user){
			//查询角色
			List<Role> roleList = userRoleDao.listRoleByUserId(user.getId());
			user.setRoleList(roleList);
			List<String> roleIdList = new ArrayList<String>(roleList.size());
			for(Role curRole : roleList){
				roleIdList.add(curRole.getId());
			}
			user.setRoleIds(StringUtils.join(roleIdList,SystemConstant.COMMA));
			
			//查询部门
			List<Depart> departList = userDepartDao.listDepartByUserId(user.getId());
			user.setDepartList(departList);
			List<String> departIdList = new ArrayList<String>(departList.size());
			for(Depart curDepart : departList){
				departIdList.add(curDepart.getId());
			}
			user.setDepartIds(StringUtils.join(departIdList, SystemConstant.COMMA));
		}
		return user;
	}
	
	/**
	 * 根据条件查询用户
	 */
	public List<User> listUserByCondition(UserCondition condition) {
		return userDao.listUserByCondition(condition);
	}
	
	/**
	 * 根据当前部门ID递归查找主管以及上级部门主管，直到topLevel级部门主管
	 * 方泉构建的工具类方法
	 * @param departId	部门ID
	 * @param topLevel	auth_depart表中的level，最高级是0，一级是1，以此类推
	 * @return
	 */
	public List<User> listManagerLoopByDepartId(String departId, Integer topLevel) {
		List<User> list = new ArrayList<User>();
		buildLoopParent(departId,list,topLevel);
		List<User> result = new ArrayList<User>();
		// 按照从上级到下级的顺序进行了重新调整
		for (int i = list.size()-1; i >= 0; i--) {
			result.add(list.get(i));
		}
		return result;
	}

	/**
	 * 根据当前部门ID递归查找主管以及上级部门主管
	 * 根据upLevel生成几级审批流
	 * 郭海军构建的工具类方法
	 * @param departId	部门ID
	 * @param topLevel	approve_process_form_set表 topLevel 逐级审批到第N级
	 * @return
	 */
	public List<User> listManagerLoopByLevel(String departId, Integer topLevel) {
		List<User> list = new ArrayList<User>();
		buildLoopParent(departId,list,0);
		List<User> result = new ArrayList<User>();
		//先根据topLevel判断要生成几级审批流
		int i = 0;
		if(list.size() < topLevel) {
			i = list.size() -1;
		}else if(list.size() >= topLevel) {
			i = topLevel - 1;
		}
		// 按照从上级到下级的顺序进行了重新调整
		for (; i >= 0; i--) {
			result.add(list.get(i));
		}
		return result;
	}
	
	/**
	 * 递归获取类型的上级集合
	 * @param cid
	 * @param categoryList
	 */
	private void buildLoopParent(String departId, List<User> resultList, Integer topLevel) {
		User obj = userDao.getManagerByDepartId(departId);
		if(null != obj){
			String parentId = obj.getDepart().getParentId();
			resultList.add(obj);
			Integer level = obj.getDepart().getLevel();
			if(null != level && level.intValue() > topLevel){
				buildLoopParent(parentId,resultList,topLevel);
			}
		}
	}
	
	/**
	 * 根据用户名获取用户
	 * @param account
	 * @return
	 */
	public User getUserByAccount(String account){
		return userDao.getUserByAccount(account);
	}
	
	/**
	 * 获取当前用户
	 * @return
	 */
	public User getCurrentUser(){
		User user = null;
		try{
			HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(); 
			HttpSession session = request.getSession(false);
			if(null != session){
				user = (User) session.getAttribute(SessionConstant.CURRENT_USER);
			}
		}catch(Exception ex){
			logger.error("", ex);
		}
		return user;
	}
	
	/**
	 * 根据角色ID查询一个用户
	 * 用于审批设置中指定角色的取用户方法
	 * @param roleId
	 * @return
	 */
	public User getOneUserByRoleId(String roleId) {
		return userDao.getOneUserByRoleId(roleId);
	}
	
	@Override
	public void saveUser(User item) {
		if(StringUtils.isBlank(item.getId())){
			String password = item.getPassword();
			if(StringUtils.isBlank(password)){
				password = "111111";
			}
			item.setPassword(EncryptUtil.encryptionPw(password));	//密码进行2次加密
			//新增用户
			userDao.add(item);
		}else{
			User old = userDao.getUserById(item.getId());
			old.setBirthday(item.getBirthday());
			old.setContact(item.getContact());
			old.setEmail(item.getEmail());
			old.setMobile(item.getMobile());
			old.setName(item.getName());
			old.setSex(item.getSex());
			old.setTel(item.getTel());
			old.setStaffId(item.getStaffId());
			//更新用户
			userDao.update(old);
			
			//删除角色
			userRoleDao.delByUserId(old.getId());
			
			//删除部门
			userDepartDao.delByUserId(old.getId());
		}
		
		//保存角色
		if(StringUtils.isNotBlank(item.getRoleIds())){
			String [] roleId = item.getRoleIds().split(",");
			for (int i = 0; i < roleId.length; i++) {
				if(StringUtils.isBlank(roleId[i])){
					continue;
				}
				
				UserRole userRole = new UserRole();
				userRole.setUserId(item.getId());
				userRole.setRoleId(roleId[i]);
				
				userRoleDao.add(userRole);
			}
		}
		
		//保存部门
		if(StringUtils.isNotBlank(item.getDepartIds())){
			String[] departId = item.getDepartIds().split(",");
			for(int i=0;i<departId.length;i++){
				if(StringUtils.isBlank(departId[i])){
					continue;
				}
				
				UserDepart userDepart = new UserDepart();
				userDepart.setUserId(item.getId());
				userDepart.setDepartId(departId[i]);
				
				userDepartDao.add(userDepart);
			}
		}
		
	}

	@Override
	public void updateState(User item) {
		userDao.updateState(item);
	}
	
	/**
	 * 更新用户信息(用户修改个人信息)
	 * @param current
	 */
	public void updateUser(User item){
		userDao.updateUser(item);
	}
	
	@Override
	public void resetPwd(User item) {
		//密码加密
		item.setPassword(EncryptUtil.encryptionPw(item.getPassword()));
		userDao.updatePassword(item);
	}
	
	/**
	 * 根据ID集合批量删除
	 * @param ids ID集合
	 */
	public void delByIds(String[] ids){
		for(String id : ids){
			//删除用户角色
			userRoleDao.delByUserId(id);
			//删除用户部门
			userDepartDao.delByUserId(id);
		}
		//删除用户
		userDao.delByIds(ids);
	}

	/**
	 * 导入文件
	 * @param realPath 文件所在路径
	 * @return 失败行数
	 */
	@Override
	public String doImport(String filePath,String createBy) {
		// 失败行，默认无
		String errorIndex = "";
		File file = new File(filePath);
		InputStream is = null;
		// 第三行开始导入
		Integer index = 2;
		try {
			is = new FileInputStream(file);
			HSSFWorkbook wb = new HSSFWorkbook(is);
			HSSFSheet sheet = wb.getSheetAt(0);
			for (int i = 2; i <= sheet.getLastRowNum(); i++) {
				HSSFRow row = sheet.getRow(i);
				if(null == row){
					continue;
				}
				index++;
				User user = new User();
				// 获取项目分类
				String staffId = StringUtils.defaultIfBlank(CommonUtil.getCellValue(row.getCell(0)),"");
				String account = StringUtils.defaultIfBlank(CommonUtil.getCellValue(row.getCell(1)),"");
				String name = StringUtils.defaultIfBlank(CommonUtil.getCellValue(row.getCell(2)),"");
				String departName = StringUtils.defaultIfBlank(CommonUtil.getCellValue(row.getCell(3)),"");
				String sex = StringUtils.defaultIfBlank(CommonUtil.getCellValue(row.getCell(4)),"");
				String birthday = StringUtils.defaultIfBlank(CommonUtil.getCellValue(row.getCell(5)),"");
				String email = StringUtils.defaultIfBlank(CommonUtil.getCellValue(row.getCell(6)),"");
				String mobile = StringUtils.defaultIfBlank(CommonUtil.getCellValue(row.getCell(7)),"");
				String tel = StringUtils.defaultIfBlank(CommonUtil.getCellValue(row.getCell(8)),"");
				
				// 账号密码都为空表示此行为为空行数据停止导入
				if(StringUtils.isBlank(account)&&StringUtils.isBlank(name)){
					break;
				}
				// 必填账号未填写停止导入并记录错误
				if(StringUtils.isBlank(account)||StringUtils.isBlank(account)){
					errorIndex = index.toString();
					break;
				}
				// 账号如果存在则跳过导入
				User oldUser = userDao.getUserByAccount(account);
				if(oldUser != null){
					continue;
				}
				user.setStaffId(staffId);
				user.setName(name);
				Integer sexType = 1;
				if(StringUtils.isNotBlank(sex)){
					if(sex.equals("女")){
						sexType = 2;
					}
					user.setSex(sexType);
				}
				if(StringUtils.isNotBlank(birthday)){
					SimpleDateFormat sdf =   new SimpleDateFormat("yyyy-MM-dd");
					user.setBirthday(sdf.parse(birthday));
				}
				user.setEmail(email);
				user.setMobile(mobile);
				user.setTel(tel);
				user.setAccount(account);
				user.setPassword(EncryptUtil.encryptionPw("111111"));
				user.setCreateBy(createBy);
				user.setUpdateBy(createBy);
				userDao.add(user);
				
				// 验证部门是否存在，不存在则自动创建,并关联用户
				if(StringUtils.isNotBlank(departName)){
					Depart depart = departDao.getDepartByName(departName);
					if(depart == null){
						depart = new Depart();
						depart.setName(departName);
						depart.setLevel(1);
						depart.setParentId("0");
						departDao.add(depart);
					}
					UserDepart userDepart = new UserDepart();
					userDepart.setUserId(user.getId());
					userDepart.setDepartId(depart.getId());
					userDepartDao.add(userDepart);
				}
				logger.info("导入成功");
			}
		}catch (Exception e) {
			//e.printStackTrace();
			errorIndex = index.toString();
			logger.info("导入第"+index+"行失败："+e.getMessage());
		}finally{
			FileUtils.deleteQuietly(file);
		}
		
		return errorIndex;
	}

	/**
	 * 根据部门ID获取用户数量
	 * @param departId
	 * @return
	 */
	@Override
	public int getUserCountByDepartId(String departId) {
		return userDepartDao.getUserCountByDepartId(departId);
	}

	/**
	 * 批量更换部门
	 * @param selIds 多用户ID
	 * @param oldDepartId 旧部门ID
	 * @param departId 部门ID
	 * @param updateBy 修改人
	 */
	@Override
	public void doMoveDepart(String selIds,String oldDepartId,String departId, String updateBy) {
		String[] ids = selIds.split(",");
		for (String id : ids) {
			// 删除用户和当前旧部门的关系
			userDepartDao.delByUserIdAndDepartId(id,oldDepartId);
			// 关联新部门
			UserDepart userDepart = new UserDepart();
			userDepart.setUserId(id);
			userDepart.setDepartId(departId);
			userDepart.setCreateBy(updateBy);
			userDepartDao.add(userDepart);
		}
	}

	/**
	 * 设置主管
	 * @param item
	 */
	@Override
	public void updateManager(User item) {
		UserDepart ud = new UserDepart();
		ud.setUserId(item.getId());
		ud.setDepartId(item.getDepartIds());
		ud.setIsManager(item.getIsManager());
		userDepartDao.updateManager(ud);
	}
	/**
	 * 根据用户id
	 * 查询用户部门中间表auth_user_depart
	 */
	public List<User> listUserDepartByUserId(String userId){
		List<Depart> departList = userDepartDao.listDepartByUserId(userId);
		UserCondition condition = new UserCondition();
		List<User> usersList = new ArrayList();
		if(departList.size() < 0) {
			return usersList;
		}
		for(Depart depart : departList) {
			if(null != depart && depart.getIsManage() != null && depart.getIsManage() == 1) {
				condition.setDepartId(depart.getId());
				List<User> userList = userDao.listUserByCondition(condition);
				for(User users : userList) {
					usersList.add(users);
				}
			}
		}
		return usersList;
		
	}
}
